#pragma once
#include <boost/random.hpp>

template<class T>
struct distribution
{ // general case, assuming T is of integral type
  typedef boost::uniform_int<> type;
};

template<>
struct distribution<float>
{ // float case
  typedef boost::uniform_real<> type;
};

template<>
struct distribution<double>
{ // double case
  typedef boost::uniform_real<> type;
};

template <typename N> 
class RandGenerator
{
	typedef typename distribution<N>::type distro_type;
	boost::lagged_fibonacci607 gen;
	distro_type dist;
	boost::variate_generator<boost::lagged_fibonacci607&, distro_type >* random;

public:
	RandGenerator(N min, N max)
	{		
		gen.seed( (uint32_t) std::time(0));
		dist = distro_type (min,max);
		random  = new boost::variate_generator<boost::lagged_fibonacci607&, distro_type >(gen,dist);
	}

	RandGenerator(N min, N max, uint32_t seed)
	{		
		gen.seed( seed );
		dist = distro_type (min,max);
		random  = new boost::variate_generator<boost::lagged_fibonacci607&, distro_type >(gen,dist);
	}

	~RandGenerator()
	{
		delete random;
	}

	N operator()()
	{
		return (*random)();
	}
};